package com.b.server.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Random;

/**
 * @Project: kim-sentinel
 * @PackageName: com.b.server.controller
 * @FileName: FusingDropController.java
 * @Description: 熔断降级规则
 * @Author: kimwu
 * @Time: 2021-01-05 16:59:26
 */
@RestController
@RequestMapping("/b")
@Slf4j
public class FusingDropController {

    /**
     * 测试sentinel 超时场景
     * 首页 -> 服务名 -> 熔断降级规则
     *
     * @return
     */
    @PostMapping("/timeout")
    //定义资源 value:设置资源的名称 blockHandler:设置限流或降级的处理函数
    @SentinelResource(value = "timeout", blockHandler = "timeoutExceptionHandler")
    public String timeout() {
        log.info("b服务模拟超时场景正在被调用");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("b服务模拟超时场景调用完毕");
        return "ok";
    }


    public String timeoutExceptionHandler(BlockException ex) {
        log.info("b服务模拟超时场景进入降级处理");
        ex.printStackTrace();
        return "系统超时，请稍候再试";
    }

    Integer abnormalProportionExceptionNum = 0;

    Integer abnormalProportionNum = 0;

    /**
     * 测试sentinel 异常比例场景
     * 首页 -> 服务名 -> 熔断降级规则
     *
     * @return
     */
    @PostMapping("/abnormalProportion")
    //定义资源 value:设置资源的名称 blockHandler:设置限流或降级的处理函数
    @SentinelResource(value = "abnormalProportion", blockHandler = "abnormalProportionExceptionHandler")
    public String abnormalProportion() {
        log.info("b服务模拟异常比例场景正在被调用");
        abnormalProportionNum++;
        int i = new Random().nextInt(3);
        if (i == 0) {
            //模拟计算异常比例
            abnormalProportionExceptionNum++;
            BigDecimal decimal = null;
            try {
                decimal = new BigDecimal(abnormalProportionExceptionNum).divide(new BigDecimal(abnormalProportionNum)).setScale(2, BigDecimal.ROUND_HALF_DOWN);
            } catch (Exception e) {
                decimal = new BigDecimal(0);
            }
            log.info("当前比例是 {} ", decimal);
            throw new RuntimeException("我异常了");
        }
        log.info("b服务模拟异常比例场景调用完毕");
        return "ok";
    }


    public String abnormalProportionExceptionHandler(BlockException ex) {
        log.info("b服务模拟异常比例场景进入降级处理");
        ex.printStackTrace();
        return "系统异常比例，请稍候再试";
    }

    Integer abnormalNumber = 0;

    /**
     * 测试sentinel 异常数场景
     * 首页 -> 服务名 -> 熔断降级规则
     *
     * @return
     */
    @PostMapping("/abnormalNumber")
    //定义资源 value:设置资源的名称 blockHandler:设置限流或降级的处理函数
    @SentinelResource(value = "abnormalNumber", blockHandler = "abnormalNumberExceptionHandler")
    public String abnormalNumber() {
        log.info("b服务模拟异常数场景正在被调用");
        //模拟计算异常比例
        abnormalNumber++;
        log.info("当前异常数 {} ", abnormalNumber);
        throw new RuntimeException("我异常了");
    }


    public String abnormalNumberExceptionHandler(BlockException ex) {
        log.info("b服务模拟异常数场景进入降级处理");
        ex.printStackTrace();
        return "系统异常数，请稍候再试";
    }

}
